///PHILOTES Source Code.  (C)2012 PhiloLabs
#pragma once


#ifndef __KeyFrame_H__
#define __KeyFrame_H__

#include "OgrePrerequisites.h"
#include "math/vector3.h"
#include "math/quaternion.h"
#include "OgreAny.h"
#include "OgreHardwareVertexBuffer.h"
#include "OgreIteratorWrappers.h"

namespace Ogre 
{

	
	
	
	class _OgreExport KeyFrame : public MemAlloc_Animation
    {
    public:

        
        KeyFrame(const AnimationTrack* parent, Real time);

		virtual ~KeyFrame() {}

        
        Real getTime(void) const { return mTime; }

		
		virtual KeyFrame* _clone(AnimationTrack* newParent) const;


    protected:
        Real mTime;
        const AnimationTrack* mParentTrack;
    };


	
	class _OgreExport NumericKeyFrame : public KeyFrame
	{
	public:
		
		NumericKeyFrame(const AnimationTrack* parent, Real time);
		~NumericKeyFrame() {}

		
		virtual const AnyNumeric& getValue(void) const;
		
		virtual void setValue(const AnyNumeric& val);

		
		KeyFrame* _clone(AnimationTrack* newParent) const;
	protected:
		AnyNumeric mValue;
	};


	
	class _OgreExport TransformKeyFrame : public KeyFrame
	{
	public:
		
		TransformKeyFrame(const AnimationTrack* parent, Real time);
		~TransformKeyFrame() {}
		
		virtual void setTranslate(const Vector3& trans);

		
		const Vector3& getTranslate(void) const;

		
		virtual void setScale(const Vector3& scale);

		
		virtual const Vector3& getScale(void) const;

		
		virtual void setRotation(const Quaternion& rot);

		
		virtual const Quaternion& getRotation(void) const;

		
		KeyFrame* _clone(AnimationTrack* newParent) const;
	protected:
		Vector3 mTranslate;
		Vector3 mScale;
		Quaternion mRotate;


	};



	
	class _OgreExport VertexMorphKeyFrame : public KeyFrame
	{
	public:
		
		VertexMorphKeyFrame(const AnimationTrack* parent, Real time);
		~VertexMorphKeyFrame() {}
		
		void setVertexBuffer(const HardwareVertexBufferSharedPtr& buf);

		
		const HardwareVertexBufferSharedPtr& getVertexBuffer(void) const;

		
		KeyFrame* _clone(AnimationTrack* newParent) const;		

	protected:
		HardwareVertexBufferSharedPtr mBuffer;

	};

	
	class _OgreExport VertexPoseKeyFrame : public KeyFrame
	{
	public:
		
		VertexPoseKeyFrame(const AnimationTrack* parent, Real time);
		~VertexPoseKeyFrame() {}

		
		struct PoseRef
		{
			
			ushort poseIndex;
			
			Real influence;

			PoseRef(ushort p, Real i) : poseIndex(p), influence(i) {}
		};
		typedef vector<PoseRef>::type PoseRefList;

		
		void addPoseReference(ushort poseIndex, Real influence);
		
		void updatePoseReference(ushort poseIndex, Real influence);
		
		void removePoseReference(ushort poseIndex);
		
		void removeAllPoseReferences(void);


		
		const PoseRefList& getPoseReferences(void) const;

		typedef VectorIterator<PoseRefList> PoseRefIterator;
		typedef ConstVectorIterator<PoseRefList> ConstPoseRefIterator;

		
		PoseRefIterator getPoseReferenceIterator(void);

		
		ConstPoseRefIterator getPoseReferenceIterator(void) const;

		
		KeyFrame* _clone(AnimationTrack* newParent) const;
		
		void _applyBaseKeyFrame(const VertexPoseKeyFrame* base);
		
	protected:
		PoseRefList mPoseRefs;

	};
	
	

}


#endif

